﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web;
using System.Web.Security;
using System.Web.Routing;
using XSTDZ.ERP.Application;

namespace XSTDZ.ERP.Infrastructure.Authentication
{
    /// <summary>
    /// 不需要进行授权验证（只需登陆成功即可访问）
    /// </summary>
    public class AvoidAuthentication : IAuthorizationFilter
    {
        private Type _controllerType;
        private string _actionName;
        private readonly ControllerContext _controllerContext;
        private readonly IList<IAuthorizationFilter> _filters;

        public AvoidAuthentication(IList<IAuthorizationFilter> filters, Type controllerType, string actionName, ControllerContext controllerContext)  
        {  
            _controllerType = controllerType;  
            _actionName = actionName;  
            _controllerContext = controllerContext;  
            _filters = filters;  
        }
        /// <summary>  
        /// 得到完整Url  
        /// </summary>  
        /// <returns></returns>  
        public string GetCurrentFullUrl(AuthorizationContext context)  
        {  
            return string.Format("{0}://{1}{2}", context.HttpContext.Request.Url.Scheme, context.HttpContext.Request.Url.Host, context.HttpContext.Request.RawUrl);  
        }
        private void RedirectToLogin(AuthorizationContext context, string url)
        {
            context.HttpContext.Response.Redirect(String.Format("{0}?ReturnUrl={1}", FormsAuthentication.LoginUrl, HttpUtility.UrlEncode(url)));
        }

        public void OnAuthorization(AuthorizationContext filterContext)
        {
            if (_filters == null)
            {
                filterContext.Result = null;
            }
            if (_controllerType.Name.ToLower() == SystemConfig.LoginControllerName.ToLower() + "controller" && _actionName.ToLower() == SystemConfig.LoginActonName.ToLower())
            {
                filterContext.Result = null;
            }
            else
            {
                bool isDeny = true;
               
                #region 处理所有不需要授权的 Controller 和 Acton


                foreach (var item in _filters)
                {
                    if (item is NoAuthorizatedAttribute)
                    {
                        var noAuthenticateItem = item as NoAuthorizatedAttribute;
                        if (noAuthenticateItem == null)
                        {
                            break;
                        }
                        if (string.IsNullOrEmpty(noAuthenticateItem.ActionName) || noAuthenticateItem.ActionName.ToLower() == _actionName.ToLower())
                        {
                            filterContext.Result = null;
                            isDeny = false;
                            break;
                        }
                    }
                }
               
                #endregion

                #region 处理需要授权的资源
                if (isDeny)
                { 
                     isDeny =!IsAuthorizated();
                }
                #endregion

                if (!isDeny)
                {
                    filterContext.Result = null;
                }
                else
                {
                    HttpUnAutharizor(filterContext);
                }
            }
        }
        //未授权，跳转到未授权页面
        private void HttpUnAutharizor(AuthorizationContext filterContext)
        {
            filterContext.Result = new RedirectToRouteResult(
              new RouteValueDictionary
                {
                    { "client", filterContext.RouteData.Values[ "client" ] },
                    { "controller", SystemConfig.HttpUnAuthorizedControllerName },
                    { "action", SystemConfig.HttpUnAuthorizedActionName },
                    { "ReturnUrl", filterContext.HttpContext.Request.RawUrl }
                });
        }
        //这个是做不好的做法，先这样，以后有好的再修改
        private bool IsAuthorizated()
        {
            var isValidate = _controllerContext.HttpContext.User.Identity.IsAuthenticated;
            if (!isValidate)
            {
                return false;
            }
            #region 获得解密后的用户ID
            var   userId= _controllerContext.HttpContext.User.Identity.Name;// _controllerContext.HttpContext.Request.Cookies[FormsAuthentication.FormsCookieName].Value;
           
            var activeId = (userId != null && !string.IsNullOrEmpty(userId.ToString()))?CryptographerLite.Decrypt(userId):Guid.Empty.ToString();
            #endregion
            #region 超级管理员不需要进行授权，默认所有权限都可以
            if (activeId == XSTDZ.ERP.Infrastructure.SystemConfig.AdminId)
            {
                return true;
            }
            #endregion

            Guid userid;
            if (string.IsNullOrEmpty(activeId))
            {
                return false;
            }
            if (!Guid.TryParse(activeId.ToString(), out userid))
            {
                return false;
            }
            return GetControllUiResource(userid);//把无权限介面元素操作权限写入ViewData中
        }

        private bool GetControllUiResource(Guid userid)
        {
            IUserService userImpl = ServiceLocator.Instance.GetService<IUserService>();
            bool exists = false;
            var userUiResourceIds = userImpl.GetUiPermissionIds(userid, _controllerType.Name.Replace("Controller", ""), _actionName,out exists).Where(t=>t!=null).ToArray();
            if (exists)
            {
                IPermisstionService permissionImpl = ServiceLocator.Instance.GetService<IPermisstionService>();
                var UiResources = permissionImpl.GetUiPermissions(_controllerType.Name.Replace("Controller", ""), _actionName).Where(t=>t!=null);//获取该页面下的页面元素
                if (UiResources != null && UiResources.Count() != 0)//若有页面子元素的维护，则启用登陆用户判断，否则该页面所有元素用户都可访问
                {
                   // var UiResourceIds = UiResources.Select(t => t.Id);
                 var UiResourceIds=  UiResources.Where(m=>!userUiResourceIds.Contains(m.Id)).Select(t => t);
                    
                  
                    #region 生成隐藏的JS代码
                    var js = "";
                    var htmlJs="";
                    foreach (var uiResource in UiResourceIds)
                    {
                        if(uiResource.IsMenu)
                        {
                             htmlJs +=  uiResource.ClientId+",";
                        }
                        else
                        {
                            js +=  uiResource.ClientId+",";
                        }

                    }
                    _controllerContext.Controller.ViewData["XSCUSERPERMISSION"] = js;
                    _controllerContext.Controller.ViewData["XSCUSERPERMISSIONHTML"] = htmlJs;
                    #endregion
                }
            }
        //  _controllerContext.Controller.ViewData["XSCUSERPERMISSION"] = "";
          return exists;
        }
    }
}
